home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 5 / Amiga Tools 5.iso / tools / developer-tools / aros / source / exec / signals / src / signal.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-16  |  3.1 KB  |  130 lines

  1. /*
  2.     $Id$
  3.     $Log$
  4.     Desc:
  5.     Lang: english
  6. */
  7. #include "exec_intern.h"
  8. #include <exec/execbase.h>
  9. #include <aros/libcall.h>
  10.  
  11. /*****************************************************************************
  12.  
  13.     NAME */
  14.     #include <clib/exec_protos.h>
  15.  
  16.     __AROS_LH2(void, Signal,
  17.  
  18. /*  SYNOPSIS */
  19.     __AROS_LA(struct Task *, task, A1),
  20.     __AROS_LA(unsigned long, signalSet, D0),
  21.  
  22. /*  LOCATION */
  23.     struct ExecBase *, SysBase, 54, Exec)
  24.  
  25. /*  FUNCTION
  26.     Send some signals to a given task. If the task is currently waiting
  27.     on these signals, has a higher priority as the current one and if
  28.     taskswitches are allowed the new task begins to run immediately.
  29.  
  30.     INPUTS
  31.     task      - Pointer to task structure.
  32.     signalSet - The set of signals to send to the task.
  33.  
  34.     RESULT
  35.  
  36.     NOTES
  37.     This function may be used from interrupts.
  38.  
  39.     EXAMPLE
  40.  
  41.     BUGS
  42.  
  43.     SEE ALSO
  44.     AllocSignal(), FreeSignal(), Wait(), SetSignal(), SetExcept()
  45.  
  46.     INTERNALS
  47.  
  48.     HISTORY
  49.     29-10-95    digulla automatically created from
  50.                 exec_lib.fd and clib/exec_protos.h
  51.     17-12-95    digulla Incorporated code by Matthias Fleischner
  52.  
  53. *****************************************************************************/
  54. {
  55.     __AROS_BASE_EXT_DECL(struct ExecBase *,SysBase)
  56.  
  57.     /* Protect the task lists against other tasks that may use Signal(). */
  58.     Disable();
  59.  
  60.     /* Set the signals in the task structure. */
  61.     task->tc_SigRecvd|=signalSet;
  62.  
  63.     /* Do those bits raise exceptions? */
  64.     if(task->tc_SigExcept&task->tc_SigRecvd)
  65.     {
  66.     /* Yes. Set the exception flag. */
  67.     task->tc_Flags|=TF_EXCEPT;
  68.  
  69.     /* task is running? Raise the exception or defer it for later. */
  70.     if(task->tc_State==TS_RUN)
  71.     {
  72.         /* Are taskswitches allowed? (Don't count own Disable() here) */
  73.         if(SysBase->TDNestCnt>=0||SysBase->IDNestCnt>0)
  74.         /* No. Store it for later. */
  75.         SysBase->AttnResched|=0x80;
  76.         else
  77.         {
  78.         /* Switches are allowed. Move the current task away. */
  79.         SysBase->ThisTask->tc_State=TS_READY;
  80.         Enqueue(&SysBase->TaskReady,&SysBase->ThisTask->tc_Node);
  81.  
  82.         /* And force a rescedule. */
  83.         Switch();
  84.         }
  85.  
  86.         /* All done. */
  87.         Enable();
  88.         return;
  89.     }
  90.     }
  91.  
  92.     /*
  93.     Is the task receiving the signals waiting on them
  94.     (or on a exception) ?
  95.     */
  96.     if(task->tc_State==TS_WAIT&&
  97.        (task->tc_SigRecvd&(task->tc_SigWait|task->tc_SigExcept)))
  98.     {
  99.     /* Yes. Move him to the ready list. */
  100.     task->tc_State=TS_READY;
  101.     Remove(&task->tc_Node);
  102.     Enqueue(&SysBase->TaskReady,&task->tc_Node);
  103.  
  104.     /* Has it a higher priority as the current one? */
  105.     if(task->tc_Node.ln_Pri>SysBase->ThisTask->tc_Node.ln_Pri)
  106.         /*
  107.         Yes. A taskswitch is necessary. Prepare one if possible.
  108.         (If the current task is not running it is already moved)
  109.         */
  110.         if(SysBase->ThisTask->tc_State==TS_RUN)
  111.         {
  112.         /* Are taskswitches allowed? */
  113.         if(SysBase->TDNestCnt>=0||SysBase->IDNestCnt>0)
  114.             /* No. Store it for later. */
  115.             SysBase->AttnResched|=0x80;
  116.         else
  117.         {
  118.             /* Switches are allowed. Move the current task away. */
  119.             SysBase->ThisTask->tc_State=TS_READY;
  120.             Enqueue(&SysBase->TaskReady,&SysBase->ThisTask->tc_Node);
  121.  
  122.             /* And force a rescedule. */
  123.             Switch();
  124.         }
  125.         }
  126.     }
  127.  
  128.     Enable();
  129. } /* Signal */
  130.